package gbase8s

import "net/url"

type DSN struct {
	user     string
	password string
	server   string
	host     string
	port     string
	database string
}

func NewDSN(host, port, user, password, server, database string) *DSN {
	return &DSN{
		user:     user,
		password: password,
		server:   server,
		host:     host,
		port:     port,
		database: database,
	}
}

func (d *DSN) WithUser(user string) *DSN {
	d.user = user
	return d
}

func (d *DSN) WithPassword(password string) *DSN {
	d.password = password
	return d
}

func (d *DSN) WithServer(server string) *DSN {
	d.server = server
	return d
}

func (d *DSN) WithHost(host string) *DSN {
	d.host = host
	return d
}

func (d *DSN) WithPort(port string) *DSN {
	d.port = port
	return d
}

func (d *DSN) WithDatabase(database string) *DSN {
	d.database = database
	return d
}

func (d *DSN) WithDSN(dsn string) *DSN {
	u, err := url.Parse(dsn)
	if err != nil {
		return d
	}
	d.user = u.User.Username()
	d.password, _ = u.User.Password()
	d.host = u.Hostname()
	d.port = u.Port()
	d.database = u.Path
	d.server = u.Query().Get("GBASEDBTSERVER")
	return d
}

func (d *DSN) String() string {
	var user *url.Userinfo
	if d.user != "" && d.password != "" {
		user = url.UserPassword(d.user, d.password)
	} else if d.user != "" {
		user = url.User(d.user)
	}
	uri := url.URL{
		Scheme: "gbase8s",
		User:   user,
		Host:   d.host + ":" + d.port,
		Path:   d.database,
		RawQuery: url.Values{
			"GBASEDBTSERVER": {d.server},
			"PROTOCOL":       {"onsoctcp"},
			"GCI_FACTORY":    {"4"},
			"GormLogTrace":   {"1"},
			"GOGCILogTrace":  {"1"},
			"sqlmode":        {"oracle"},
			"delimident":     {"1"},
		}.Encode(),
	}
	return uri.String()
}
